<?php

declare(strict_types=1);

namespace app\api\controller;

use app\api\service\OilStoreService;
use app\api\service\OilXiaojuService;
use app\BaseController;
use app\middleware\ApiUserAuth;
use app\middleware\OilTokenCheck;
use app\model\BaseSupplier;
use app\model\OilAgentChannel;
use app\model\OilOrder;
use app\model\OilStore;
use app\model\OilStoreItem;
use app\Request;
use think\middleware\SessionInit;

/**
 * @apiDefine oilUserApi 油品手机端接口
 */
class OilApi extends BaseController
{
    protected $middleware = [
        //SessionInit::class,
        ApiUserAuth::class.':continue' => ['only' => ['getStoreList']],
        ApiUserAuth::class => ['except' => ['homeConfig', 'getStoreList', 'sendSms']],
        OilTokenCheck::class => ['except' => ['homeConfig', 'getStoreList', 'sendSms']],
    ];

    /**
     * @api  {GET} /api/oilApi/getStoreList 加油站列表
     * @apiName getStoreList
     * @apiGroup oilUserApi
     * @apiDescription 首页列表加油站信息获取，分页拉取时候最后一次如果拉取到的数据是空表示最后一页
     * @apiParam {String} cnid  页面上的cnid参数
     * @apiParam {String} lon  精度 火星坐标系
     * @apiParam {String} lat 维度
     * @apiParam {String} [store_name]  加油站名称
     * @apiParam {String} lon 经度 火星坐标系
     * @apiParam {String} lat 纬度
     * @apiParam {String} item_name 油品 0# 92# 98# 等 0#代表柴油
     * @apiParam {Int} page=1 分页页码
     * @apiParam {Int} list_rows=10 分页大小
     * @apiParam {String} [sort=distance] 排序依据 distance表示距离
     * @apiParam {String} [sort_type=asc] 排序升降序  asc升序 desc降序
     * @apiParam {String} [brand_name] 品牌
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data":
     *      "store" : [{
     * 		    "id": 1705,
     * 		    "supplier_id": 2,
     * 		    "store_id": "5235678813162575872", // 加油站id
     * 		    "store_name": "单商户入驻门店11",
     * 		    "store_logo": "https:\/\/view.didistatic.com\/static\/dcms\/2r6k9w50wd8_156x156.jpeg",
     * 		    "city_name": "杭州市",
     * 		    "province_name": "浙江省",
     * 		    "address": "西溪水岸花苑",
     * 		    "lon": 120.04969,//经度
     * 		    "lat": 30.28198,  // 纬度
     * 		    "brand_name": "中国海油",  // 品牌名称
     * 		    "business_hours_start": 0,
     * 		    "business_hours_end": 24,
     * 		    "distance": 0,  // 距离 单位米
     * 		    "item_name": "92#",  // 油品规格
     * 		    "city_price": 6.94,  // 发行价
     * 		    "store_price": 6.94, // 油站价
     * 		    "vip_price": 6.94  // 会员价
     * 	     }],
     *      "is_login" : 1 //登录状态
     *
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function getStoreList(Request $request)
    {
        $rules = [
            'lon' => 'require',
            'lat' => 'require',
            'item_name' => 'require',
        ];
        $messages = ['lon.require' => '请授权地理位置', 'lat.require' => '请授权地理位置', 'item_name.require' => '请选择油品', 'require' => '非法参数'];

        $where = $request->only(['item_name' => '92#', 'store_name' => '', 'brand_name' => '']);
        $locat = $request->only(['lon', 'lat']);
        $paginate = $request->only(['list_rows' => 10, 'page' => 1]);
        if (!$paginate['list_rows']) {
            $paginate['list_rows'] = 10;
        }
        if (!$paginate['page']) {
            $paginate['page'] = 1;
        }
        $sort = $request->only(['sort' => 'distance', 'sort_type' => 'asc']);

        $sort['sort'] = $sort['sort'] ? $sort['sort'] : 'distance';
        $sort['sort_type'] = $sort['sort_type'] ? $sort['sort_type'] : 'asc';

        // 排序处理
        if ('price' == $sort['sort']) {
            $sort = ' store_price '.$sort['sort_type'];
            $sort .= ' ,distance asc ';
        } else {
            if (!$sort['sort']) {
                $sort['sort'] = 'distance';
            }
            $sort = $sort['sort'].' '.$sort['sort_type'];
        }

        // 是否登录状态 暂时没用到只是个标识
        $isLogin = 0;
        if (!empty($request->user)) {
            $isLogin = 1;
        }

        if ($msg = dmjValidate($rules, $messages, array_merge($locat, $where))) {
            return fail($msg, 0, ['store' => [], 'is_login' => $isLogin]);
        }

        // 渠道校验
        $oilAgentChannel = OilAgentChannel::where('status', 1)->find($request->param('cnid', 0));
        if (!$oilAgentChannel) {
            return fail('渠道不存在', 0, ['store' => [], 'is_login' => $isLogin]);
        }

        $agentInfo = $oilAgentChannel->agent()->where('is_deleted', 0)->where('status', 1)->find();
        if (!$agentInfo) {
            return fail('代理不存在', 0, ['store' => [], 'is_login' => $isLogin]);
        }

        if (!$agentInfo['oil_service']) {
            return fail('代理不存在', 0, ['store' => [], 'is_login' => $isLogin]);
        }

        $list = invoke(OilStoreService::class)->getOilStoreList($where, $paginate, $sort, $locat);

        if ($list['code'] || !$list['data']) {
            return success('', ['store' => [], 'is_login' => $isLogin]);
        }

        $list = $list['data'];

        if ($isLogin) {
            // 根据 list 去查询价格
            $param = $request->only(['lon', 'lat', 'item_name' => '92#']);
            $param['store_id_list'] = array_column($list['data'], 'store_id');
            $param['mobile'] = $request->user['mobile'];

            $param['lon'] = floatval($param['lon']);
            $param['lat'] = floatval($param['lat']);

            $storePriceList = invoke(OilXiaojuService::class)->queryStorePrice($param);

            if ($storePriceList['code']) { // 获取价格失败   vip_price 默认成 store_price
                foreach ($list['data'] as $k => $v) {
                    $list['data'][$k]['item_name'] = $v['item'][0]['item_name'];
                    $list['data'][$k]['city_price'] = fen2yuan($v['item'][0]['city_price']);
                    $list['data'][$k]['store_price'] = fen2yuan($v['item'][0]['store_price']);
                    $list['data'][$k]['vip_price'] = $list['data'][$k]['store_price']; // 默认取值 store_price
                    unset($list['data'][$k]['item']);
                }
            } else {
                $storePriceList = $storePriceList['data'];
                foreach ($list['data'] as $k => $v) {
                    $list['data'][$k]['item_name'] = $v['item'][0]['item_name'];
                    $list['data'][$k]['city_price'] = fen2yuan($v['item'][0]['city_price']);
                    $list['data'][$k]['store_price'] = fen2yuan($storePriceList[$v['store_id']]['storePrice']);
                    $list['data'][$k]['vip_price'] = fen2yuan($storePriceList[$v['store_id']]['vipPrice']); // 默认取值 store_price
                    unset($list['data'][$k]['item']);
                }
            }
        } else {
            // 没有登录情况下
            foreach ($list['data'] as $k => $v) {
                $list['data'][$k]['item_name'] = $v['item'][0]['item_name'];
                $list['data'][$k]['city_price'] = fen2yuan($v['item'][0]['city_price']);
                $list['data'][$k]['store_price'] = fen2yuan($v['item'][0]['store_price']);
                $list['data'][$k]['vip_price'] = '?'; // 默认取值 ?
                unset($list['data'][$k]['item']);
            }
        }

        doLog(json_encode($list['data'][0] ?? [], JSON_UNESCAPED_UNICODE));

        return success('', ['store' => $list['data'], 'is_login' => $isLogin]);
    }

    /**
     * @api  {GET} /api/oilApi/queryEnergyUrl 加油站连接
     * @apiName queryEnergyUrl
     * @apiGroup oilUserApi
     * @apiDescription 点击跳转加油站前 需要先触发该接口 获取加油站连接
     * @apiParam {String} cnid  页面上的 cnid 参数
     * @apiParam {String} lon  精度 火星坐标系
     * @apiParam {String} lat 维度
     * @apiParam {String} store_id  加油站id ，来自加油站列表的store_id字段
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data": {
     * 		"link": "http:www.baidu.com"   //跳转url
     * 	}
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function queryEnergyUrl(Request $request)
    {
        $rules = [
            'lon' => 'require',
            'lat' => 'require',
            'store_id' => 'require',
        ];
        $messages = ['lon.require' => '请授权地理位置', 'lat.require' => '请授权地理位置', 'store_id.require' => '请选择加油站'];
        $param = $request->only(['lon', 'lat', 'store_id', 'item_name' => '92#']);
        if ($msg = dmjValidate($rules, $messages, $param)) {
            return fail($msg);
        }

        $param['lon'] = floatval($param['lon']);
        $param['lat'] = floatval($param['lat']);
        $param['mobile'] = $request->user['mobile'];  // todo 从用户里获取
        $param['out_user_id'] = $request->user['platform']['id'];  // todo 从用户里获取

        // 获取 供应商信息 针对不同供应商做处理
        $supplierInfo = BaseSupplier::where('code', OIL_SUPPLIER_ALIAS['xiaoju']['alias'])->find();

        if (!$supplierInfo) {
            return fail('非法参数');
        }
        switch ($supplierInfo->code) {
            case 'xiaoju':
                $list = invoke(OilXiaojuService::class)->queryEnergyUrl(batchCamelize($param));

                return serviceResponse($list);
            break;
        }
    }

    /**
     * @api  {GET} /api/oilApi/userOrder  用户订单列表
     * @apiName userOrder
     * @apiGroup oilUserApi
     * @apiDescription 用户订单列表 ，字段意可以参考 订单详情页字段
     * @apiParam {String} cnid  页面上的cnid参数
     * @apiParam {Int} [refund[0,1]] 不填查询全部 1表示退款 0 表示完成
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data": [{
     * 		"id": 1,  // 我们平台的订单id 点击详情使用
     * 		"gun_no": "", //  油枪编号
     * 		"item_name": "92#", // 油规格
     * 		"pay_time": "2021-09-18 12:00:00",
     * 		"total_amount": 18, // 总价
     * 		"pay_amount": 17, // 实付价
     * 		"pay_type": "支付宝支付",
     * 		"status": "已支付",
     * 		"store_name": "xx加油站", // 油规格
     * 		"refund_status": 0, // 退款状态
     * 		"refund_at": "2021-09-18 12:00:00", // 退款时间
     * 		"store_logo": "http://a.png"  //加油站logo
     * 	}]
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function userOrder(Request $request)
    {
        //  代理商下订单
        $where = [
            ['status', '=', 1],
            ['user_id', '=', $request->user['id']],
            //['cnid', '=', $request->user['platform']['app_id']],
        ];
        if ($request->has('refund')) {
            $where[] = ['refund_status', '=', $request->param('refund')];
        }

        $agentId = 0;
        $oilAgentChannel = OilAgentChannel::withTrashed()->where('status', 1)->find($request->param('cnid', 0));
        if ($oilAgentChannel) {
            $agentId = $oilAgentChannel->agent()->where('is_deleted', 0)->where('status', 1)->value('id');
        }

        if ($agentId) {
            $where[] = ['agent_id', '=', $agentId];
        } else {
            $where[] = ['cnid', '=', $request->user['platform']['app_id']];
        }

        $list = OilOrder::field('id,gun_no,item_name,pay_time,total_amount,pay_amount,pay_type,status,store_name,refund_status,refund_at')
            ->withJoin(['store' => function ($query) {
                $query->WithField(['id']);
            }])->field('store.store_logo')
            ->where($where)->page($request->param('page', 1), $request->param('pageize', 10))
            ->order('pay_time', 'desc')
            ->select();

        if (!$list->isEmpty()) {
            $statusArr = ['0' => '未支付', '1' => '已支付', '-1' => '已退款'];
            $payTypeArr = ['0' => '其他', '1' => '支付宝支付', '2' => '微信支付'];
            $list = $list->toArray();
            foreach ($list as $k => $v) {
                $list[$k]['total_amount'] = fen2yuan($v['total_amount']);
                $list[$k]['pay_amount'] = fen2yuan($v['pay_amount']);
                if ($v['refund_status']) {
                    $v['status'] = '-1';
                }
                $list[$k]['status'] = $statusArr[$v['status']];
                $list[$k]['pay_type'] = $payTypeArr[$v['pay_type']];
                unset($list[$k]['store']);
            }
        } else {
            $list = [];
        }

        return success('', $list);
    }

    /**
     * @api  {GET} /api/oilApi/orderDetail  订单详情
     * @apiName orderDetail
     * @apiGroup oilUserApi
     * @apiDescription 用户订单详情
     * @apiParam {String} cnid  页面上的 cnid 参数
     * @apiParam {Int} id  订单列表页返回的id
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data": {
     * 		"id": 1,
     * 		"gun_no": "5", // 油枪编号
     * 		"item_name": "92#", // 油规格
     * 		"pay_time": "2021-09-18 19:00:00", // 下单时间
     * 		"pay_amount": 0, // 支付金额
     * 		"total_amount": 0,  //总金额
     * 		"pay_type": "支付宝支付", // 支付方式
     * 		"status": "已支付",  // 付费 退款状态
     * 		"quantity": 1,  //加油量
     * 		"store_name": "呆萌价加油站",  // 加油站名称
     * 		"refund_status": 0,  // 1 退款
     * 		"refund_at": null, // 如果refund_status =1 表示退款 此时才有时间 否则null
     * 		"store_logo": "https:\/\/static.bs.didistatic.com\/static\/gsbs\/anything\/3ed40366-28fb-4277-b0eb-e721ea356ecb.",
     * 		"cut_amount": 0, // 优惠金额
     * 		"price": "9.8"  //单价
     * 	}
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function orderDetail(Request $request)
    {
        $info = OilOrder::field('id,gun_no,out_order_id,item_name,pay_time,pay_amount,total_amount,pay_type,status,quantity,store_name,refund_status,refund_at')
            ->withJoin(['store' => function ($query) {
                $query->WithField(['id']);
            }])->field('store.store_logo')
            ->where('user_id', $request->user['id'])->find($request->param('id', 0));

        if (!$info) {
            return fail('订单不存在');
        }

        $statusArr = ['0' => '未支付', '1' => '已支付', '-1' => '已退款'];
        $payTypeArr = ['0' => '其他', '1' => '支付宝支付', '2' => '微信支付'];
        $info['cut_amount'] = round(($info['total_amount'] - $info['pay_amount']) / 100, 2); //优惠金额

        $info['quantity'] = floatval($info['quantity']);
        if ($info['quantity']) {
            $info['price'] = round($info['total_amount'] / ($info['quantity'] * 100), 2); //单价
        } else {
            $info['price'] = '被除数为0';
        }

        $info['total_amount'] = fen2yuan($info['total_amount']);
        $info['pay_amount'] = fen2yuan($info['pay_amount']);
        if ($info['refund_status']) {
            $info['status'] = '-1';
        }
        $info['status'] = $statusArr[$info['status']];
        $info['pay_type'] = $payTypeArr[$info['pay_type']];

        unset($info['store']);

        return success('', $info->toArray());
    }

    /**
     * @api  {GET} /api/oilApi/homeConfig  首页配置
     * @apiName homeConfig
     * @apiGroup oilUserApi
     * @apiDescription 首页配置
     * @apiParam {String} cnid  页面上的 cnid 参数
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data": {
     * 		"brand": ["中国航油", "中国石油", "中航石油", "中化道达尔", "中国海油", "中正石油", "中胜石油", "昆仑石油", "金盾石化"],  // 品牌
     * 		"item_name": ["98#", "92#", "95#", "优途95#", "LPG"],   // 油品规格
     * 		"sort": {  // 排序
     * 			"field": {
     * 				"distance": "距离",
     * 				"price": "价格"
     * 			},
     * 			"type": {
     * 				"sort": "升序",
     * 				"desc": "降序"
     * 			}
     * 		}
     * 	}
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function homeConfig(Request $request)
    {
        $data = [];
        $data['brand'] = (OilStore::where('brand_name', '<>', '')->distinct(true)->column('brand_name')); // 品牌
        $data['item_name'] = (OilStoreItem::where('item_name', '<>', '')->distinct(true)->column('item_name')); // 油品规格
        sort($data['item_name']);
        array_unshift($data['item_name'], '92#');
        $data['item_name'] = array_unique($data['item_name']);
        $data['sort'] = ['field' => ['distance' => '距离', 'price' => '价格'], 'type' => ['sort' => '升序', 'desc' => '降序']];

        if ($request->user) {  //暂时没用到只是个标识
            $data['is_login'] = 1;
        } else {
            $data['is_login'] = 0;
        }

        return success('', $data);
    }

    /**
     * @api  {GET} /api/oilApi/sendSms  短信验证码
     * @apiName sendSms
     * @apiGroup oilUserApi
     * @apiDescription 短信验证码
     * @apiParam {String} cnid  页面上的 cnid 参数
     * @apiParam {String} mobile 手机号
     * @apiSuccessExample {json} 成功返回
     * {
     * 	"code": 200,
     * 	"message": "",
     * 	"data": {}
     * }
     * @apiUse  AuthHeader
     * @apiUse  BaseReturn
     * @apiVersion 1.0.0
     */
    public function sendSms(Request $request)
    {
        // echo cache('login_18922396855');
        // exit;
        $rules = [
            'cnid' => 'require',
            'mobile' => 'require',
        ];
        $messages = ['mobile.require' => '请填写手机号', 'require' => '缺少必须参数'];
        $param = $request->only(['cnid', 'mobile']);

        if ($msg = dmjValidate($rules, $messages, $param)) {
            return fail($msg);
        }

        if (in_array($param['mobile'], ['18922396855', '15980755471'])) { // 白名单不需要验证码校验
            return success('短信发送成功，请查收');
        }

        // todo 发验证码
        $randCode = mt_rand(10000, 99999);
        $res = sendSms('您的登录验证码是：'.$randCode, $param['mobile']);
        if ($res['code']) {
            return fail($res['msg']);
        }

        cache('login_'.$param['mobile'], $randCode, 600); // 缓存5分钟

        return success('短信发送成功，请查收');
    }
}
